#coding:utf-8

from lxml import etree
import time
import MySQLdb
import traceback
import config
from utils.mysql_util import MySQLUtil
from utils.logger_factory import LOG_INFO, LOG_ERR

import os
import sys
reload(sys)
sys.setdefaultencoding("UTF8")

class BookDataProcessor(object):
    def __init__(self):
        self._total_books_count = 0
        self._saved_books_count = 0
        self._error_books_count = 0
        self._db = MySQLUtil()

    def close(self):
        self._db.close()

    def process(self, xml_data_path, data_type, is_delta = True):
        t1 = time.time()
        for book_info in self.parse_xml_books(xml_data_path, data_type, is_delta):
            sql = self.build_insert_query(book_info, data_type)
            try:
                self._db.save_or_update(sql)
            except Exception, e:
                LOG_ERR("failed save or update data: %s, error: %s" % (book_info, traceback.format_exc()))
                self._error_books_count += 1

        t2 = time.time()
        print "System parsed %d Books, saved or updated %d, %d error Bookds " \
                "Children Books in %s, usedTime: %d" % (self._total_books_count,
                                                self._saved_books_count,
                                                self._error_books_count,
                                                xml_data_path,
                                                t2 - t1)

        LOG_INFO("System parsed %d Books, saved or updated %d, %d error Bookds " \
                 "Children Books in %s, usedTime: %d" % (self._total_books_count,
                                                        self._saved_books_count,
                                                        self._error_books_count,
                                                        xml_data_path,
                                                        t2 - t1))

    def parse_xml_books(self, xml_data_path, data_type, is_delta):
        root = etree.iterparse(xml_data_path, events=('end',), tag='item_data')

        for event, elem in root:
            book_info, needed = self.build_data_from_element(elem)
            self._total_books_count += 1

            if len(book_info) and needed:
                self._saved_books_count += 1
                if is_delta:
                    item_delta_status = book_info.get("item_delta_status")
                    # 删除 item_delta_status 标志
                    del book_info["item_delta_status"]

                    # 将URL字段置空
                    if item_delta_status == "REMOVE":
                        for key in config.ITEM_DELTA_CLEAR_TAGS:
                            book_info[key] = None
                yield book_info
                # else:

            # Release Memory
            elem.clear()
            while elem.getprevious() is not None:
                del elem.getparent()[0]

        # delete xml source file
        os.remove(xml_data_path)

    # 构造sql语句
    def build_insert_query(self, dic, data_type):

        table_name = None
        if data_type == config.BookConfig.CNBOOKS_CHILDREN_TYPE:
            table_name = config.BookConfig.CNBOOKS_CHILDREN_TABLE
        else:
            table_name = config.BookConfig.CNBOOKS_IMPORTED_TABLE

        base_query = 'replace into %s(' % (table_name)
        base_values = 'values('
        for key in dic:
            base_query += '%s,' % (key)
            value = dic[key]
            if value != None:
                value = MySQLdb.escape_string(value)
            base_values += "'%s'," % (value)

        base_query = base_query[:-1]
        base_values = base_values[:-1]
        base_query += ')'
        base_values += ')'

        return base_query + base_values + ';'

    def build_data_from_element(self, elem):
        needed = False
        book_info = {}

        for item in elem.iterchildren():
            if item.tag == 'item_basic_data':
                for basic_data in item.iterchildren():
                    if basic_data.tag not in config.XML_EXCLUDE_TAGS:
                        book_info[basic_data.tag] = basic_data.text

            elif item.tag == 'merch_cat_list':
                for merch_item in item.iterchildren():
                    for cat_item in merch_item.iterchildren():
                        if (cat_item.tag == 'merch_cat_name'):
                            book_info[cat_item.tag] = cat_item.text
                        if (cat_item.tag == 'merch_cat_path'):
                            if ((cat_item.text.find("图书/类别/少儿/") != -1) or (cat_item.text.find("Children's Books") != -1)):
                                needed = True
                                book_info[cat_item.tag] = cat_item.text
                                break

            elif item.tag == "item_delta_status":
                book_info[item.tag] = item.text

        return book_info, needed


